﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ComApp
{
    public class ReflectService
    {

        private static ReflectService instance;
        public static ReflectService Instance
        {
            get
            {
                return instance ?? (instance = new ReflectService());
            }
        }


        public void ClearEventHandler(object eventObject, object targetObject)
        {
            var eventObjectType = eventObject.GetType();
            var eventList = eventObjectType.GetEvents().ToList();
            eventList.ForEach(eventInfo =>
            {
                var f = this.GetEventFiled(eventObjectType, eventInfo.Name);
                var hlist = f.GetValue(eventObject) as EventHandler;
                if (hlist != null)
                    foreach (var h in hlist.GetInvocationList())
                    {
                        if (h.Target == null)
                        {
                            if (h.Method.DeclaringType.Name == targetObject.GetType().Name)
                                eventInfo.RemoveEventHandler(eventObject, h);
                        }
                        else
                        {
                            if (h.Target == targetObject)
                                eventInfo.RemoveEventHandler(eventObject, h);
                        }
                    }
            });
        }

        public bool IsRegistEventHandler(object eventObject, string eventName, object targetObject)
        {
            var eventObjectType = eventObject.GetType();
            var eventList = eventObjectType.GetEvents().ToList();
            var eventInfo = eventList.Where(e => e.Name == eventName).SingleOrDefault();
            if (eventInfo == null)
                throw new ApplicationException(string.Format("事件{0}.{1}不存在", eventObjectType.Name, eventName));
            var f = this.GetEventFiled(eventObjectType, eventInfo.Name);
            var hlist = f.GetValue(eventObject) as EventHandler;
            if (hlist == null)
                return false;
            foreach (var h in hlist.GetInvocationList())
            {
                if (h.Target == null)
                {
                    if (h.Method.DeclaringType.Name == targetObject.GetType().Name)
                        return true;
                }
                else
                {
                    if (h.Target == targetObject)
                        return true;
                }
            }
            return false;
        }

        public bool IsRegistEventHandler<T>(object eventObject, string eventName)
        {
            var eventObjectType = eventObject.GetType();
            var eventList = eventObjectType.GetEvents().ToList();
            var eventInfo = eventList.Where(e => e.Name == eventName).SingleOrDefault();
            if (eventInfo == null)
                throw new ApplicationException(string.Format("事件{0}.{1}不存在", eventObjectType.Name, eventName));
            var f = this.GetEventFiled(eventObjectType, eventInfo.Name);
            var hlist = f.GetValue(eventObject) as EventHandler;
            if (hlist == null)
                return false;
            foreach (var h in hlist.GetInvocationList())
            {
                if (h.Method.DeclaringType.Name == typeof(T).Name)
                    return true;
            }
            return false;

        }

        private FieldInfo GetEventFiled(Type type, string eventName)
        {
            BindingFlags all = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
            FieldInfo fieldInfo = type.GetFields(all).Where(f => f.Name == eventName).SingleOrDefault();
            if (fieldInfo != null)
                return fieldInfo;
            return this.GetEventFiled(type.BaseType, eventName);
        }




    }
}
